package com.isolate.run;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;
import org.apache.commons.io.IOUtils;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.*;

/**
 * @author gaozhongbao
 * @date 2020/08/14
 **/
@Slf4j
public class HammyThread implements Runnable {

    private static final int DEFAULT_TEXT_BUFFER_SIZE = 8196;

    private CommandLine commandLine;

    private DefaultExecutor defaultExecutor;

    private WebSocketSession webSocketSession;

    private WebSocketMessage<?> webSocketMessage;

    private byte[] defaultInputBuffer = new byte[DEFAULT_TEXT_BUFFER_SIZE];

    private InputStream inputStream;

    private OutputStream outputStream;

    private OutputStream errorStream;

    public HammyThread(WebSocketSession webSocketSession, WebSocketMessage webSocketMessage) {
        this.webSocketSession = webSocketSession;
        this.webSocketMessage = webSocketMessage;
        this.inputStream = new ByteArrayInputStream(defaultInputBuffer);
        this.outputStream = new ByteArrayOutputStream(DEFAULT_TEXT_BUFFER_SIZE);
        this.errorStream = new ByteArrayOutputStream(DEFAULT_TEXT_BUFFER_SIZE);
    }

    public CommandLine getCommandLine() {
        return commandLine;
    }

    @Override
    public void run() {
        while (webSocketSession.isOpen()) {
            String messagePayLoad = webSocketMessage.getPayload().toString();
            try {
                IOUtils.read(inputStream, messagePayLoad.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }

            String outPut = outputStream.toString();
            try {
                webSocketSession.sendMessage(new TextMessage(outPut));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void execute(String command_0, String command_1) {
        commandLine = new CommandLine(command_0);
        commandLine.addArgument(command_1);
        PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(outputStream, errorStream, inputStream);
        defaultExecutor.setStreamHandler(pumpStreamHandler);

        try {
            int execute = defaultExecutor.execute(commandLine);
            log.info("execute:[{}]", execute);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
